package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.constants.RedisConstants;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author tc
 * @since 2023-04-16
 */
@Service
@RequiredArgsConstructor
public class LikedRecordServiceRedisImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {


    private final RedisTemplate redisTemplate;
    private final RabbitMqHelper mqHelper;

    /**
     * 点赞或者取消点赞
     *
     * @param formDTO
     */
    @Override
    public void likedRemark(LikeRecordFormDTO formDTO) {
        //判断是否是点赞记录
        Boolean su = formDTO.getLiked() ? liked(formDTO) : noliked(formDTO);
        //判断点赞是否存在
        if (!su) {
            return;
        }
        //执行成功，获取点赞总数
        Long likedTimes = redisTemplate.opsForSet()
                .size(RedisConstants.LIKES_BIZ_KEY_PREFIX + formDTO.getBizId());

        if (likedTimes == null){
            return;
        }
        //缓存总点赞数到Redis
        redisTemplate.opsForSet().add(RedisConstants.LIKES_TiMES_KEY_PREFIX + formDTO.getBizType(),
        formDTO.getBizId().toString(),
        likedTimes);
    }

    /**
     * 查询点赞状态
     *
     * @param bizIds
     * @return
     */
    @Override
    public Set<Long> userLiked(List<Long> bizIds) {
        //获取登录用户
        Long userId = UserContext.getUser();
        //查询点赞状态

        List<Object> objects = redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                StringRedisConnection src  = (StringRedisConnection) connection;
                for (Long bizId : bizIds) {
                    String  key =  RedisConstants.LIKES_BIZ_KEY_PREFIX + bizId;
                    src.sInterStore(key,userId.toString());
                }
                return null;
            }
        });
        //返回结果
        for (int i = 0;i< objects.size();i++){
            Boolean o = (Boolean) objects.get(i);
            if (o){
                bizIds.add(bizIds.get(i));
            }
        }
        //返回结果
        return IntStream.range(0,objects.size()).filter(i -> (Boolean) objects.get(i)).mapToObj(bizIds::get).collect(Collectors.toSet());

    }


    //取消点赞Redis优化
    private Boolean noliked(LikeRecordFormDTO formDTO) {
        //获取用户
        Long userId = UserContext.getUser();
        //获取key
        String key =  RedisConstants.LIKES_BIZ_KEY_PREFIX + formDTO.getBizType();
        //执行SREM命令
        Long remove =  redisTemplate.opsForZSet().remove(key,userId.toString());
        return remove != null && remove > 0;
    }

    //点赞Redis优化
    private Boolean liked(LikeRecordFormDTO formDTO) {
        //获取用户id
        Long userId = UserContext.getUser();
        //获取key
        String key = RedisConstants.LIKES_BIZ_KEY_PREFIX + formDTO.getBizId();
        //执行SADD命令
        Long add = redisTemplate.opsForSet().add(key, userId.toString());
        return add != null && add > 0;
    }
}
